package com.mall.order.service;

import com.ctg.mse.common.cache.RedisSingle;
import com.ctg.mse.common.exception.BizException;
import com.ctg.mse.common.model.error.CommonCode;
import com.ctg.mse.common.model.result.ResultGeneralModel;
import com.ctg.mse.common.utils.EncryptUtil;
import com.ctg.mse.common.utils.JacksonUtil;
import com.mall.mall.api.MallApi;
import com.mall.order.constants.OrderConstants;
import com.mall.order.controller.OrderController;
import com.mall.order.dao.entity.TOrder;
import com.mall.order.dao.mapper.TOrderMapper;
import com.mall.order.vo.CreateOrderInfo;
import com.mall.order.vo.SimpleProductInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import static com.mall.order.constants.OrderConstants.DEFAULT_USER_ID;

/**
 * @Description: OrderService
 * @Author: zhouzh
 * @CreateTime: 2022-10-21  11:40
 */
@Service
public class OrderService {

    private final static Logger LOGGER = LoggerFactory.getLogger(OrderService.class);


    @Autowired
    private TOrderMapper tOrderMapper;

    @Autowired
    private MallApi mallApi;

    @Autowired
    private RedisSingle redisSingle;

    public TOrder createOrder(Double price, List<SimpleProductInfo> productInfos){

        TOrder tOrder = new TOrder();
        //没有用户系统，暂时使用default user
        tOrder.setUserId(DEFAULT_USER_ID);
        tOrder.setProduct(JacksonUtil.encode(productInfos));
        tOrder.setDescription("普通订单");
        tOrder.setPrice(BigDecimal.valueOf(price));
        tOrder.setCreateTime(new Date());
        //待支付
        tOrder.setState(1);

        //查询缓存，存在则不下单，不存在则添加缓存（5s过期），下单，保证5s内只能下一个相同的单
        String key = EncryptUtil.md5(JacksonUtil.encode(tOrder));
        LOGGER.info("缓存key：" + key);

        if(redisSingle.exists(key)){
            LOGGER.error("下单频次过高，请等待后再下单");
            throw new BizException(CommonCode.UNKNOWN_ERROR,"下单频次过高，请等待后再下单");
        }else{
            redisSingle.set(key,"",5L);
        }

        //调用mall服务，减库存
        ResultGeneralModel<Boolean> subRes = mallApi.subtractInventory(JacksonUtil.encode(productInfos));
        if(!subRes.isSuccess()){
            String errorInfo = subRes.getErrorMsg() + ",userId=" + DEFAULT_USER_ID + ",tOrder=" + tOrder;
            LOGGER.error(errorInfo);
            throw new BizException(CommonCode.UNKNOWN_ERROR,errorInfo);
        }

        tOrderMapper.insert(tOrder);
        LOGGER.info("订单创建成功：" + tOrder);

        //redis里记录销量
        for(SimpleProductInfo cur : productInfos){
            Long curNum = null;
            String curKey = "product" + cur.getId().toString();
            if(redisSingle.exists(curKey)){
                curNum = Long.parseLong(redisSingle.get(curKey));
            }else{
                curNum = 0L;
            }
            redisSingle.set(curKey, String.valueOf((curNum + cur.getNumber())));
        }

        return tOrder;
    }

    public TOrder modifyState(Long orderId, Integer state){
        TOrder tOrder = new TOrder();
        tOrder.setId(orderId);
        tOrder.setState(state);

        int modify = tOrderMapper.updateById(tOrder);
        if(modify != 0){
            LOGGER.info("订单状态修改成功：" + tOrder);
            return tOrder;
        }else{
            return null;
        }
    }

    public List<Long> getProductsSales(List<Long> productIds){
        List<Long> res = new ArrayList<>();
        for(Long productId : productIds){
            String seals = redisSingle.get("product" + productId);
            if(seals == null){
                res.add(0L);
            }else{
                res.add(Long.parseLong(seals));
            }
        }
        return res;
    }


}
